#include "xregister_handle.h"
#include <XTools.h>
#include <protobuf/xmsg_com.pb.h>

using namespace std;
using namespace xmsg;

static xmsg::XServiceMap *static_service_map = nullptr;
static std::mutex static_server_map_mutex;

void XRegisterHandle::RegisterReq(xmsg::XMsgHead *head, XMsg *msg)
{
    XCOM_LOG_DEBUG("RegisterReq");
    // 解析请求
    xmsg::XRegisterReq req;
    bool ret = req.ParseFromArray(msg->data, msg->size);
    xmsg::XMessageRes res;
    if (!ret)
    {
        XCOM_LOG_DEBUG("RegisterReq ParseFromArray error");
        res.set_return_(xmsg::XMessageRes::FAIL);
        res.set_msg("register ParseFromArray error!");
        SendMsg(xmsg::MSG_REGISTER_RES, &res);
        return;
    }
    std::string serverName = req.name();
    if (serverName.empty())
    {
        XCOM_LOG_DEBUG("serverName.empty()");
        res.set_return_(xmsg::XMessageRes::FAIL);
        res.set_msg("serverName.empty()!");
        SendMsg(xmsg::MSG_REGISTER_RES, &res);
        return;
    }
    std::string serverIP = req.ip();
    if (serverIP.empty())
    {
        serverIP = client_ip();
    }
    unsigned short serverPort = req.port();
    if (serverPort == 0 || serverPort > 65535)
    {
        XCOM_LOG_DEBUG("serverPort is error");
        res.set_return_(xmsg::XMessageRes::FAIL);
        res.set_msg("serverPort is error");
        SendMsg(xmsg::MSG_REGISTER_RES, &res);
        return;
    }
    XCOM_LOG_INFO("接收到用户注册信息:" << serverName << ":" << serverPort << ":" << serverIP);
    {
        auto lock = std::unique_lock<std::mutex>(static_server_map_mutex);
        // 是否已经创建 static_server_map
        if (static_service_map == nullptr)
        {
            static_service_map = new xmsg::XServiceMap();
        }
        // 获取服务列表
        auto service_map = static_service_map->mutable_service_map();
        // 是否注册过serverName类型的服务
        if (service_map->find(serverName) == service_map->end())
        {
            // 没有注册，则船舰serverName类型的服务列表
            service_map->operator[](serverName) = xmsg::XServiceMap::XServiceList();
        }
        xmsg::XServiceMap::XServiceList &service_list = (*service_map)[serverName];
        for (auto it = service_list.services().begin(); it != service_list.services().end(); it++)
        {
            if (it->ip() == serverIP && it->port() == serverPort)
            {
                XCOM_LOG_DEBUG("服务已经注册过:" << serverName << ":" << serverPort << ":" << serverIP);
                res.set_return_(xmsg::XMessageRes::SUCCESS);
                res.set_msg("OK");
                SendMsg(xmsg::MSG_REGISTER_RES, &res);
                return;
            }
        }
        auto service = service_list.add_services();
        service->set_name(serverName);
        service->set_port(serverPort);
        service->set_ip(serverIP);
    }
    XCOM_LOG_INFO("注册成功:" << serverName << ":" << serverPort << ":" << serverIP);
    res.set_return_(xmsg::XMessageRes::SUCCESS);
    res.set_msg("OK");
    SendMsg(xmsg::MSG_REGISTER_RES, &res);
}

void XRegisterHandle::GetServiceReq(xmsg::XMsgHead *head, XMsg *msg)
{
    // 暂时只支持 获取所有服务
    XCOM_LOG_DEBUG("接收到服务的发送请求");
    xmsg::XGetServiceReq req;
    xmsg::XServiceMap res;
    res.mutable_res()->set_return_(xmsg::XMessageRes::FAIL);
    bool ret = req.ParseFromArray(msg->data, msg->size);
    if (!ret)
    {
        XCOM_LOG_DEBUG("GetServiceReq ParseFromArray error");
        res.mutable_res()->set_msg("GetServiceReq ParseFromArray error!");
        SendMsg(xmsg::MSG_GET_SERVICE_RES, &res);
        return;
    }
    xmsg::XServiceMap *send_map = &res;
    
    // 填写获取个数
    res.set_type(req.type());
    string service_name = req.name();

    XCOM_LOG_INFO("接收到服务的发送请求:" << req.name());
    auto lock = std::unique_lock<std::mutex>(static_server_map_mutex);
    if(!static_service_map){
        static_service_map = new xmsg::XServiceMap();
    }
    // 返回全部
    if(req.type() == xmsg::XServiceType::ALL){
        send_map = static_service_map;
    }else{ // 返回单个
        auto smap = static_service_map->mutable_service_map();
        if(smap&& smap->find(req.name()) != smap->end()){
            (*send_map->mutable_service_map())[service_name]=(*smap)[service_name];
        }
    }
    lock.unlock();
    send_map->set_type(req.type());
    static_service_map->mutable_res()->set_msg("OK");
    send_map->mutable_res()->set_return_(xmsg::XMessageRes::SUCCESS);
    SendMsg(MSG_GET_SERVICE_RES, send_map);
}
